package com.maimao.goods.aop;

import io.seata.core.context.RootContext;
import io.seata.core.exception.TransactionException;
import io.seata.tm.api.GlobalTransaction;
import io.seata.tm.api.GlobalTransactionContext;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

/**
 * 拦截业务方法
 * 如果抛异常，且在全局事务中，则手动回滚，避免ControllerAdvice捕获异常无法回滚
 * 解决方案来自：http://seata.io/zh-cn/blog/seata-spring-boot-aop-aspectj.html
 * @deprecated 这种方式必须去掉Feign降级，且在超时等会触发Feign降级的异常时还是无法回滚，因此索性直接在降级方法中回滚了
 * @author MaoLin Wang
 * @date 2021/4/5 3:31 下午
 */
@Slf4j
@Component
@Deprecated
//@Aspect
public class NeedGlobalTractionAspect {

    @Pointcut("execution(* com.maimao.goods.service.*.*(..))")
    public void txAnnotation(){

    }

    @AfterThrowing(throwing = "throwable", pointcut = "txAnnotation()")
    public void doAfterReturning(Throwable throwable) {
        if (!StringUtils.isBlank(RootContext.getXID())){
            try {
                GlobalTransactionContext.reload(RootContext.getXID()).rollback();
                log.error("回滚,事务XID：{}",RootContext.getXID());
            } catch (TransactionException e) {
                e.printStackTrace();
                log.error("回滚失败，事务XID：{}",RootContext.getXID());
            }
        }
    }
    @AfterReturning(pointcut ="txAnnotation()", returning = "result")
    public void afterReturning(JoinPoint point, Object result) throws TransactionException {
        log.info("方法执行结束:{}", result);
       /* if ((Boolean) result) {
            if (!StringUtils.isBlank(RootContext.getXID())) {
                log.info("分布式事务Id:{}", RootContext.getXID());
                GlobalTransactionContext.reload(RootContext.getXID()).commit();
            }
        }*/
    }
}
